// 简易 IndexedDB 封装：用于按工作区持久化解压出的条目（包含目录与文件/压缩包）

export type PersistedEntry = {
	key: string
	workspaceId: string
	path: string
	type: 'file' | 'dir'
	isBinary: boolean
	size: number
	content?: Blob // 仅文件
}

const DB_NAME = 'LogVision'
const STORE_NAME = 'files'

function openDb(): Promise<IDBDatabase> {
	return new Promise((resolve, reject) => {
		const request = indexedDB.open(DB_NAME, 1)
		request.onupgradeneeded = () => {
			const db = request.result
			if (!db.objectStoreNames.contains(STORE_NAME)) {
				const store = db.createObjectStore(STORE_NAME, { keyPath: 'key' })
				store.createIndex('workspaceId', 'workspaceId', { unique: false })
				store.createIndex('path', 'path', { unique: false })
			}
		}
		request.onsuccess = () => resolve(request.result)
		request.onerror = () => reject(request.error)
	})
}

export async function saveWorkspaceEntries(workspaceId: string, entries: { path: string; type: 'file' | 'dir'; isBinary: boolean; bytes?: Uint8Array }[]): Promise<void> {
	const db = await openDb()
	await new Promise<void>((resolve, reject) => {
		const tx = db.transaction(STORE_NAME, 'readwrite')
		const store = tx.objectStore(STORE_NAME)
		for (const e of entries) {
			const blob = e.type === 'file' && e.bytes
				? new Blob([e.bytes!], { type: e.isBinary ? 'application/octet-stream' : 'text/plain' })
			: undefined
			const rec: PersistedEntry = {
				key: `${workspaceId}:${e.path}`,
				workspaceId,
				path: e.path,
				type: e.type,
				isBinary: e.isBinary,
				size: e.bytes ? e.bytes.byteLength : 0,
				content: blob
			}
			store.put(rec)
		}
		tx.oncomplete = () => resolve()
		tx.onerror = () => reject(tx.error)
	})
}

export async function countWorkspaceEntries(workspaceId: string): Promise<number> {
	const db = await openDb()
	return new Promise<number>((resolve, reject) => {
		const tx = db.transaction(STORE_NAME, 'readonly')
		const store = tx.objectStore(STORE_NAME)
		const index = store.index('workspaceId')
		let count = 0
		index.openCursor(IDBKeyRange.only(workspaceId)).onsuccess = (e: any) => {
			const cursor: IDBCursorWithValue | null = e.target.result
			if (cursor) {
				count++
				cursor.continue()
			} else {
				resolve(count)
			}
		}
		tx.onerror = () => reject(tx.error)
	})
}

export async function listWorkspacePaths(workspaceId: string, prefix?: string, limit = 500): Promise<string[]> {
	const db = await openDb()
	return new Promise<string[]>((resolve, reject) => {
		const tx = db.transaction(STORE_NAME, 'readonly')
		const store = tx.objectStore(STORE_NAME)
		const index = store.index('workspaceId')
		const paths: string[] = []
		index.openCursor(IDBKeyRange.only(workspaceId)).onsuccess = (e: any) => {
			const cursor: IDBCursorWithValue | null = e.target.result
			if (cursor) {
				const rec = cursor.value as PersistedEntry
				if (!prefix || rec.path.startsWith(prefix)) {
					paths.push(rec.path)
					if (paths.length >= limit) {
						resolve(paths)
						return
					}
				}
				cursor.continue()
			} else {
				resolve(paths)
			}
		}
		tx.onerror = () => reject(tx.error)
	})
}

// 根据正则匹配路径，最多返回 maxMatches 条（用于只取有限数量的压缩包文件）
export async function findWorkspacePathsByRegex(
	workspaceId: string,
	pattern: RegExp,
	maxMatches = 400
): Promise<string[]> {
  const db = await openDb()
  return new Promise<string[]>((resolve, reject) => {
    const tx = db.transaction(STORE_NAME, 'readonly')
    const store = tx.objectStore(STORE_NAME)
    const index = store.index('workspaceId')
    const results: string[] = []
    let totalPaths = 0
    let checkedPaths = 0
    
    console.log('[IndexedDB] Starting regex search for workspace:', workspaceId, 'pattern:', pattern.toString())
    
    index.openCursor(IDBKeyRange.only(workspaceId)).onsuccess = (e: any) => {
      const cursor: IDBCursorWithValue | null = e.target.result
      if (cursor) {
        const rec = cursor.value as PersistedEntry
        totalPaths++
        
        // 提取文件名（basename）进行匹配，而不是完整路径
        const basename = rec.path.split('/').pop() || ''
        
        // 只对可能相关的路径进行详细日志
        if (rec.path.includes('LogDump') || rec.path.includes('.gz')) {
          checkedPaths++
          console.log(`[IndexedDB] Checking path ${checkedPaths}: ${rec.path} -> basename: ${basename} -> match: ${pattern.test(basename)}`)
        }
        
        if (pattern.test(basename)) {
          results.push(rec.path)
          console.log(`[IndexedDB] MATCHED: ${rec.path}`)
          if (results.length >= maxMatches) {
            resolve(results)
            return
          }
        }
        cursor.continue()
      } else {
        console.log(`[IndexedDB] Finished scanning. Total paths: ${totalPaths}, Checked: ${checkedPaths}, Matched: ${results.length}`)
        resolve(results)
      }
    }
    tx.onerror = () => reject(tx.error)
  })
}

export async function getWorkspaceFile(workspaceId: string, path: string): Promise<PersistedEntry | undefined> {
	const db = await openDb()
	return new Promise((resolve, reject) => {
		const tx = db.transaction(STORE_NAME, 'readonly')
		const store = tx.objectStore(STORE_NAME)
		const req = store.get(`${workspaceId}:${path}`)
		req.onsuccess = () => resolve(req.result as PersistedEntry | undefined)
		req.onerror = () => reject(req.error)
	})
}

// 别名函数，为了保持命名一致性
export const getArchiveEntry = getWorkspaceFile

// 保存解压后的转储日志数据
export async function saveDumpLogData(
  workspaceId: string,
  dumpType: 'framework' | 'operation' | 'app',
  dumpIndex: number,
  logData: string
): Promise<void> {
  const db = await openDb()
  await new Promise<void>((resolve, reject) => {
    const tx = db.transaction(STORE_NAME, 'readwrite')
    const store = tx.objectStore(STORE_NAME)
    
    // 修正：解压后的文件路径应该是 dump_info/LogDump/{type}.log.{index}（没有.gz）
    const fileName = dumpType === 'app' ? 'app' : dumpType
    const path = `dump_info/LogDump/${fileName}.log.${dumpIndex}`
    const key = `${workspaceId}:${path}`
    
    const entry: PersistedEntry = {
      key,
      workspaceId,
      path,
      type: 'file',
      isBinary: false,
      size: logData.length,
      content: new Blob([logData], { type: 'text/plain' })
    }
    
    console.log(`[ArchiveDB] 保存转储日志: ${path}`)
    
    const req = store.put(entry)
    req.onsuccess = () => resolve()
    req.onerror = () => reject(req.error)
    
    tx.onerror = () => reject(tx.error)
  })
}

// 获取解压后的转储日志数据
export async function getDumpLogData(
  workspaceId: string,
  dumpType: 'framework' | 'operation' | 'app',
  dumpIndex: number
): Promise<string | null> {
  // 修正：查询正确的路径格式
  const fileName = dumpType === 'app' ? 'app' : dumpType
  const path = `dump_info/LogDump/${fileName}.log.${dumpIndex}`
  
  console.log(`[ArchiveDB] 查询转储日志: ${path}`)
  
  const entry = await getWorkspaceFile(workspaceId, path)
  
  if (entry && entry.content instanceof Blob) {
    console.log(`[ArchiveDB] 找到转储日志: ${path}, 大小: ${entry.size}`)
    return await entry.content.text()
  }
  
  console.log(`[ArchiveDB] 未找到转储日志: ${path}`)
  return null
}

// 获取工作区所有已解压的转储日志
export async function getAllDumpLogs(
  workspaceId: string,
  dumpType: 'framework' | 'operation' | 'app'
): Promise<{ index: number; data: string }[]> {
  const db = await openDb()
  return new Promise<{ index: number; data: string }[]>((resolve, reject) => {
    const tx = db.transaction(STORE_NAME, 'readonly')
    const store = tx.objectStore(STORE_NAME)
    const index = store.index('workspaceId')
    
    // 修正：匹配正确的路径格式
    const fileName = dumpType === 'app' ? 'app' : dumpType
    const pathPattern = `^dump_info/LogDump/${fileName}\\.log\\.(\\d+)$`
    
    console.log(`[ArchiveDB] 查找所有 ${dumpType} 转储日志，路径模式: ${pathPattern}`)
    
    const foundEntries: { index: number; blob: Blob; path: string }[] = []
    
    index.openCursor(IDBKeyRange.only(workspaceId)).onsuccess = (e: any) => {
      const cursor: IDBCursorWithValue | null = e.target.result
      if (cursor) {
        const rec = cursor.value as PersistedEntry
        // 匹配转储日志路径格式：dump_info/LogDump/{type}.log.{index}
        const match = rec.path.match(pathPattern)
        if (match && rec.content instanceof Blob) {
          const dumpIndex = parseInt(match[1])
          foundEntries.push({ index: dumpIndex, blob: rec.content, path: rec.path })
          console.log(`[ArchiveDB] 找到转储日志: ${rec.path}, 索引: ${dumpIndex}`)
        }
        cursor.continue()
      } else {
        // 事务完成后，异步读取所有 Blob 内容
        console.log(`[ArchiveDB] 游标完成，找到 ${foundEntries.length} 个 ${dumpType} 转储日志`)
        
        Promise.all(
          foundEntries.map(async (entry) => ({
            index: entry.index,
            data: await entry.blob.text()
          }))
        ).then((results) => {
          // 按索引排序
          results.sort((a, b) => a.index - b.index)
          console.log(`[ArchiveDB] 转储日志数据读取完成，总计 ${results.length} 个`)
          resolve(results)
        }).catch(reject)
      }
    }
    tx.onerror = () => reject(tx.error)
  })
}

// 删除特定的转储日志数据
export async function deleteDumpLogData(
  workspaceId: string,
  dumpType: 'framework' | 'operation' | 'app',
  dumpIndex: number
): Promise<void> {
  const fileName = dumpType === 'app' ? 'app' : dumpType
  const path = `dump_info/LogDump/${fileName}.log.${dumpIndex}`
  const key = `${workspaceId}:${path}`
  
  console.log(`[ArchiveDB] 删除转储日志: ${path}`)
  
  const db = await openDb()
  await new Promise<void>((resolve, reject) => {
    const tx = db.transaction(STORE_NAME, 'readwrite')
    const store = tx.objectStore(STORE_NAME)
    
    const req = store.delete(key)
    req.onsuccess = () => {
      console.log(`[ArchiveDB] 成功删除转储日志: ${path}`)
      resolve()
    }
    req.onerror = () => reject(req.error)
    
    tx.onerror = () => reject(tx.error)
  })
}

// 删除某个工作区特定类型的所有转储日志数据
export async function deleteAllDumpLogsOfType(
  workspaceId: string,
  dumpType: 'framework' | 'operation' | 'app'
): Promise<void> {
  const fileName = dumpType === 'app' ? 'app' : dumpType
  const pathPattern = `^dump_info/LogDump/${fileName}\\.log\\.(\\d+)$`
  
  console.log(`[ArchiveDB] 删除所有 ${dumpType} 转储日志，路径模式: ${pathPattern}`)
  
  const db = await openDb()
  await new Promise<void>((resolve, reject) => {
    const tx = db.transaction(STORE_NAME, 'readwrite')
    const store = tx.objectStore(STORE_NAME)
    const index = store.index('workspaceId')
    const keysToDelete: string[] = []
    
    index.openCursor(IDBKeyRange.only(workspaceId)).onsuccess = (e: any) => {
      const cursor: IDBCursorWithValue | null = e.target.result
      if (cursor) {
        const rec = cursor.value as PersistedEntry
        // 匹配转储日志路径格式：dump_info/LogDump/{type}.log.{index}
        const match = rec.path.match(pathPattern)
        if (match) {
          keysToDelete.push(rec.key)
          console.log(`[ArchiveDB] 标记删除转储日志: ${rec.path}`)
        }
        cursor.continue()
      } else {
        // 批量删除所有匹配的转储日志
        console.log(`[ArchiveDB] 开始批量删除 ${keysToDelete.length} 个转储日志`)
        
        const deletePromises = keysToDelete.map(key => 
          new Promise<void>((deleteResolve, deleteReject) => {
            const deleteReq = store.delete(key)
            deleteReq.onsuccess = () => deleteResolve()
            deleteReq.onerror = () => deleteReject(deleteReq.error)
          })
        )
        
        Promise.all(deletePromises).then(() => {
          console.log(`[ArchiveDB] 成功删除 ${keysToDelete.length} 个 ${dumpType} 转储日志`)
          resolve()
        }).catch(reject)
      }
    }
    tx.onerror = () => reject(tx.error)
  })
}


